﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FunDraw.LayerInfos
{
    //图层类别
    public enum LAYERTYPE { POINT=0,LINE=1,EQUATION=2,SIN=3,COS=4}

    /// <summary>
    /// 图层信息类
    /// </summary>
    public class LayerInfo
    {
        public LAYERTYPE LayerType { get; set; } = LAYERTYPE.POINT;
        public string LayerName { get; set; } = "POINT";
        public string id { get; set; } = new Guid().ToString();

        public bool Visable { get; set; } = true;
        /// <summary>
        /// 字符形式的类名称
        /// </summary>
        public string FriendlyType
        {
            get
            {
                return LayerType.ToString();
            }
        }

        /// <summary>
        /// 构造图层信息类
        /// </summary>
        public LayerInfo(LAYERTYPE lt=LAYERTYPE.POINT,string lyName="POINT")
        {
            LayerType = lt;
            LayerName = lyName;
            id = Guid.NewGuid().ToString();
        }
        /// <summary>
        /// 获取类信息
        /// </summary>
        /// <returns>类信息字符串ID,Name:Type</returns>
        public override string ToString()
        {
            return string.Format("{0},{1}:{2}", id, LayerName, FriendlyType);
        }

    }

    /// <summary>
    /// 图层信息列表类
    /// </summary>
    public  class LayerInfoList
    {
        private List<LayerInfo> _lylist = new List<LayerInfo>();
        private Dictionary<LAYERTYPE, int> _lyCounters = new Dictionary<LAYERTYPE, int>();

        /// <summary>
        /// 通过ID检索图层信息在列表中的索引位置
        /// </summary>
        /// <param name="ID">图层信息ID</param>
        /// <returns>图层信息在图层信息列表中的索引,-1表示没有找到</returns>
        private int FindLayerIndexByID(string ID)
        {
            int res = -1;
            try
            {
                for(int i =0;i<=_lylist.Count-1;i++)
                {
                    string itemid = _lylist[i].id;
                    if(itemid==ID)
                    {
                        res = i;
                        break;
                    }
                }
            }
            catch
            {

            }
            return res;
        }

        /// <summary>
        /// 增加一个图层类别的计数器每增加一个图层对应的类别计数器增加1
        /// </summary>
        /// <param name="lyType">图层类别</param>
        /// <returns>增加后的数值</returns>
        private int IncreaseCounter(LAYERTYPE lyType)
        {
            int res = 0;
            if(_lyCounters.ContainsKey(lyType))
            {
                res = _lyCounters[lyType] +1;
                _lyCounters[lyType] = res;
            }
            else
            {
                res = 1;
                _lyCounters.Add(lyType, res);
            }

            return res;
        }

        /// <summary>
        /// 减少指定图层类别的计数
        /// </summary>
        /// <param name="lyType">图层类别</param>
        /// <returns>减少后的数量</returns>
        private int ReduceCounter(LAYERTYPE lyType)
        {
            int res = 0;
            
            if(_lyCounters.ContainsKey(lyType))
            {
                res = _lyCounters[lyType];
                if(res<=1)
                {
                    // 当前类型的计数是1的时候，直接移除该类型的计数器并将结果记录为0
                    _lyCounters.Remove(lyType);
                    res = 0;
                }
                else if(res>1)
                {
                    // 当前类型的计数是大于1的时候，将计数的值减少1并将减少后的计数返回
                    _lyCounters[lyType] = --res;
                }
            }
            return res;
        }

        /// <summary>
        /// 增加一个新图层
        /// </summary>
        /// <param name="lyType">图层类别</param>
        /// <returns>图层信息类</returns>
        public LayerInfo AppendNewLayerInfo(LAYERTYPE lyType)
        {
            try
            {
                // 新增后的计数
                int cnt = IncreaseCounter(lyType);
                string ly_name = string.Format("{0}_{1}",lyType.ToString(),cnt);
                LayerInfo lyinfo = new LayerInfo(lyType, ly_name);
                _lylist.Add(lyinfo);
                return lyinfo;
            }
            catch(Exception ex)
            {
                throw new Exception(string.Format("自动命名添加新的图层出错:{0}",ex.Message.ToString()));
            }  
        }

        /// <summary>
        /// 增加一个新的图层
        /// </summary>
        /// <param name="lyType">图层类别</param>
        /// <param name="lyName">图层名称</param>
        /// <returns>图层信息类</returns>
        public LayerInfo AppendNewLayerInfo(LAYERTYPE lyType,string lyName)
        {
            try
            {
                int cnt = IncreaseCounter(lyType);
                LayerInfo lyinfo = new LayerInfo(lyType, lyName);
                _lylist.Add(lyinfo);
                return lyinfo;
            }
            catch(Exception ex)
            {
                throw new Exception(string.Format("命名添加新的图层出错:{0}", ex.Message.ToString()));
            }
        }
        /// <summary>
        /// 通过图层id获取图层信息
        /// </summary>
        /// <param name="lyid">图层id</param>
        /// <returns>获取图层信息</returns>
        public LayerInfo GetLayerInfoByID(string lyid)
        {
            LayerInfo result = null;
            try
            {
                foreach(LayerInfo res in _lylist)
                {
                    if(res.id==lyid)
                    {
                        result = res;
                        break;
                    }
                }
            }
            catch(Exception ex)
            {
                string info = string.Format("通过id获取图层信息失败,异常信息为:{0}", ex.Message.ToString());
                throw new Exception(info);
            }
            return result;
        }
        /// <summary>
        /// 从图层列表中移除一个图层
        /// </summary>
        /// <param name="lyID">图层ID</param>
        /// <returns>返回被删除的索引</returns>
        public int RemoveLayerByID(string lyID)
        {
            try
            {
                // 获取索引
                int ly_index = FindLayerIndexByID(lyID);
                if (ly_index >= 0)
                {
                    // 得到完成的图层信息对象
                    LayerInfo lyinfo = _lylist[ly_index];
                    // 获取图层类别
                    LAYERTYPE lytype = lyinfo.LayerType;
                    // 减少对应图层类别计数器的值
                    ReduceCounter(lytype);
                    // 在信息列表中删除当前图层信息
                    _lylist.RemoveAt(ly_index);
                }
                return ly_index;
            }
            catch(Exception ex)
            {
                string msg = "根据ID从图层列表中删除出错";
                throw new Exception(string.Format("{0}:{1}",msg, ex.Message.ToString()));
            }
        }

        /// <summary>
        /// 根据ID查找图层信息类，并在列表中向上移动图层位置
        /// </summary>
        /// <param name="ID">图层ID</param>
        public void MoveUp(string ID)
        {
            try
            {
                // 获取索引
                int ly_index = FindLayerIndexByID(ID);
                if(ly_index>0)
                {
                    LayerInfo tmp = _lylist[ly_index - 1];
                    _lylist[ly_index - 1] = _lylist[ly_index];
                    _lylist[ly_index] = tmp;
                }
            }
            catch (Exception ex)
            {
                string msg = "根据ID上移图层出错";
                throw new Exception(string.Format("{0}:{1}", msg, ex.Message.ToString()));
            }
        }

        /// <summary>
        /// 根据图层信息ID查找图层，并在列表中向下移动图层位置
        /// </summary>
        /// <param name="ID"></param>
        public void MoveDown(string ID)
        {
            try
            {
                // 获取索引
                int ly_index = FindLayerIndexByID(ID);
                // 保障图层存在且不是最后一层
                if(ly_index<_lylist.Count-1&&ly_index>=0)
                {
                    LayerInfo tmp = _lylist[ly_index + 1];
                    _lylist[ly_index +1] = _lylist[ly_index];
                    _lylist[ly_index] = tmp;
                }
            }
            catch (Exception ex)
            {
                string msg = "根据ID下移图层出错";
                throw new Exception(string.Format("{0}:{1}", msg, ex.Message.ToString()));
            }
        }


        /// <summary>
        /// 通过ID获取图层索引
        /// </summary>
        /// <param name="id">图层id</param>
        /// <returns>图层索引</returns>
        public int GetLayerIndexByID(string id)
        {
            int res = -1;
            int idx = 0;
            while(idx<_lylist.Count)
            {
                LayerInfo lyinfo = _lylist[idx];
                if(lyinfo.id==id)
                {
                    res = idx;
                    break;
                }
                idx++;
            }
            return res;
        }

    }
}
